package com.bp.system.service.impl;

import com.bp.common.constant.UserConstants;
import com.bp.common.core.domain.TreeSelect;
import com.bp.common.exception.BusinessException;
import com.bp.common.utils.DateUtils;
import com.bp.common.utils.StringUtils;
import com.bp.system.domain.SysRegion;
import com.bp.system.mapper.SysRegionMapper;
import com.bp.system.service.ISysRegionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 区域Service业务层处理
 *
 * @author shaominjie
 * @date 2020-08-21
 */
@Service
public class SysRegionServiceImpl implements ISysRegionService {
    @Resource
    private SysRegionMapper regionMapper;
    /**
     * 查询区域
     *
     * @param regionId 区域ID
     * @return 区域
     */
    @Override
    public SysRegion selectById(Long regionId) {
        return regionMapper.selectById(regionId);
    }

    /**
     * 查询区域列表
     *
     * @param sysRegion 区域
     * @return 区域
     */
    @Override
    public List<SysRegion> selectList(SysRegion sysRegion) {
        return regionMapper.selectList(sysRegion);
    }

    /**
     * 新增区域
     *
     * @param sysRegion 区域
     * @return 结果
     */
    @Override
    public int insert(SysRegion sysRegion) {
        SysRegion parent = regionMapper.selectById(sysRegion.getParentId());
        // 如果父节点不为"正常"状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(parent.getStatus())) {
            throw new BusinessException("区域停用，不允许新增");
        }
        sysRegion.setAncestors(parent.getAncestors() + "," + sysRegion.getParentId());
        sysRegion.setCreateTime(DateUtils.getNowDate());
        return regionMapper.insert(sysRegion);
    }

    /**
     * 修改区域
     *
     * @param sysRegion 区域
     * @return 结果
     */
    @Override
    public int update(SysRegion sysRegion) {
        sysRegion.setUpdateTime(DateUtils.getNowDate());
        return regionMapper.update(sysRegion);
    }

    /**
     * 批量删除区域
     *
     * @param regionIds 需要删除的区域ID
     * @return 结果
     */
    @Override
    public int deleteByIds(Long[] regionIds) {
        if(checkInUsing(regionIds)){
            throw new BusinessException("当前选择的区域正在使用中，请移除绑定关系再删除!");
        }
        // 部门关联不得删除
        return regionMapper.deleteByIds(regionIds);
    }

    /**
     * 删除区域信息
     *
     * @param regionId 区域ID
     * @return 结果
     */
    @Override
    public int deleteById(Long regionId) {
        return regionMapper.deleteById(regionId);
    }


    //<editor-fold desc="自定义">
    @Override
    public List<TreeSelect<Long>> buildRegionTreeSelect(List<SysRegion> regions) {
        List<SysRegion> regionTrees = buildRegionTree(regions);
        return regionTrees.stream().map(this::regionTree).collect(Collectors.toList());
    }
    private boolean checkInUsing(Long[] regionIds) {
        return regionMapper.selectInUsingById(regionIds) > 0;
    }


    //<editor-fold desc="内部方法">
    private List<SysRegion> buildRegionTree(List<SysRegion> list) {
        List<SysRegion> returnList = new ArrayList<>();
        List<Long> tempList = new ArrayList<>();
        for (SysRegion item : list) {
            tempList.add(item.getRegionId());
        }
        for (SysRegion item : list) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(item.getParentId())) {
                recursionFn(list, item);
                returnList.add(item);
            }
        }
        if (returnList.isEmpty()) {
            returnList = list;
        }
        return returnList;
    }
    private TreeSelect<Long> regionTree(SysRegion region){
        TreeSelect<Long> regionTree = new TreeSelect<>();
        regionTree.setId(region.getRegionId());
        regionTree.setLabel(region.getRegionName());
        List<SysRegion> childList = (List<SysRegion>) region.getChildren();
        regionTree.setChildren(childList.stream().map(this::regionTree).collect(Collectors.toList()));
        return regionTree;
    }
    /**
     * 递归列表
     */
    private void recursionFn(List<SysRegion> list, SysRegion t) {
        // 得到子节点列表
        List<SysRegion> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysRegion tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysRegion n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }
    /**
     * 得到子节点列表
     */
    private List<SysRegion> getChildList(List<SysRegion> list, SysRegion t) {
        List<SysRegion> tlist = new ArrayList<>();
        for (SysRegion n : list) {
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().equals(t.getRegionId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }
    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysRegion> list, SysRegion t) {
        return getChildList(list, t).size() > 0;
    }
    //</editor-fold>
    //</editor-fold>
}
